<?php


class UserClass
{

    
    /**
     * Insert a new record in tbl_user and return associative array: ('id', 'gname', 'surname', 'email')
     * On error return associative array: ('error')
     * Require associative array: ('gname', 'surname', 'password', 'email')
     *
     * @param array $user
     * @return array
     */
    function create($user, $overWriteExisting = false)
    {
        global $DBobject, $SITE;
        if ($res = $this->retrieveByUserObjectId($user['user_object_id'])) {
            if ($overWriteExisting) {
                $sql = "UPDATE tbl_user SET 
                    user_gname = :gname,
                    user_email = :email,
                    user_sex = :sex,
                    user_password = :password,
                    user_modified = now()
                WHERE user_id = :id ";
                $params = [
                    ':id'=>$res['user_id'],
                    ':gname'=>$user['name'],
                    ':email'=>$user['email'],
                    ':sex'=>$user['sex'],
                    ':password'=>getPass($res['user_username'], $user['password'])
                ];
                $DBobject->wrappedSql($sql, $params);
                saveInLog('Edit', 'tbl_user', $res['user_id']);
                return [
                    "id" => $res['user_id'],
                    "oid" => $res['user_object_id'],
                    "gname" => $user['name'],
                    "surname" => "",
                    "sex" => $user['sex'],
                    "email" => $user['email'],
                    "phone" => $user['phone'],
                    "user_hearabout" => $res['user_hearabout']
                ];
            } else {
                return array ('error' => "'{$user['user_object_id']}' 已经被注册");
                //删除用户并重新注册
                //$this->DeleteUSer($res['user_id']);
                //$this->create($user, $overWriteExisting);
            }
        } else {
            $temp_str = getPass($user['username'], $user['password']);
            $params = array (
                ":user_object_id" => $user['user_object_id'],
                ":username" => $user['username'],
                ":gname" => ucwords($user['gname']),
                ":surname" => ucwords($user['surname']),
                ":email" => $user['email'],
                ":phone" => $user['phone'],
                ":password" => $temp_str,
                ":user_site" => $SITE,
                ":want_promo" => $user['want_promo'],
                ":user_hearabout" => $user['user_hearabout'],
                ":user_warning" => $user['user_warning'],
                ":ip" => $_SERVER['REMOTE_ADDR'],
                ":browser" => $_SERVER['HTTP_USER_AGENT']
            );
            
            $sql = "INSERT INTO tbl_user (
                user_object_id,
                user_username,
                user_gname,
                user_surname,
                user_email,
                user_phone,
                user_password,
                user_site,
                user_want_promo,
                user_hearabout,
                user_warning,
                user_ip,
                user_browser,
                user_created
            ) values (
                :user_object_id,
                :username,
                :gname,
                :surname,
                :email,
                :phone,
                :password,
                :user_site,
                :want_promo,
                :user_hearabout,
                :user_warning,
                :ip,
                :browser,
                now()
            )";
            if ($DBobject->wrappedSql($sql, $params)) {
                $userId =  $DBobject->wrappedSqlIdentity();
                $result = array (
                        "id" => $userId,
                        "gname" => $user['gname'],
                        "surname" => $user['surname'],
                        "email" => $user['email'],
                        "phone" => $user['phone'],
                        "user_hearabout" => $user['user_hearabout'],
                        "user_want_promo" => $user['user_want_promo']
                );
                saveInLog('Add', 'tbl_user', $userId);
            } else {
                $result = array ('error' => '网络连接错误，请重试！');
            }
            return  $result;
        }
    }
    
    
    /**
     * Update password field of a specific record in tbl_user and return associative array: ('success')
     * On error return associative array: ('error')
     * Require associative array: ( 'email', 'password', 'old_password')
     *
     * @param array $data
     * @return array
     */
    public function updatePassword($data)
    {
        global $DBobject;
        $res = $this->Authenticate($data['email'], $data['old_password']);
        if ($res['error']) {
            return array ('error' => '原始密码错误。');
        } else {
            $temp_str = getPass($data['cardId'], $data['password']);
            $params = array (
                    ":id" => $res['id'],
                    ":password" => $temp_str,
                ":ip" => $_SERVER['REMOTE_ADDR'],
                ":browser" => $_SERVER['HTTP_USER_AGENT']
            );
            $sql = "UPDATE tbl_user SET user_password = :password, user_ip = :ip,user_browser = :browser,user_modified = now() WHERE user_id = :id ";
            if ($DBobject->wrappedSql($sql, $params)) {
                saveInLog('Edit', 'tbl_user', $res['id']);
                return array ('success' => '密码更新成功。');
            } else {
                return array ('error' => '网络连接错误，请重试！');
            }
        }
    }

    /**
     * Get a single non-deleted record from tbl_user given the username
     * On error return false
     * Require string: username
     *
     * @param string $uname
     * @return mixed
     */
    public function retrieveByUserObjectId($uoid)
    {
        global $DBobject;
    
        $sql = "SELECT * FROM tbl_user
                WHERE user_object_id = :uoid AND user_deleted IS NULL";

        $res  = $DBobject->wrappedSql($sql, array( ":uoid" => $uoid ));

        return $res[0];
    }

    /**
     * Get a single non-deleted record from tbl_user given the username
     * On error return false
     * Require string: username
     *
     * @param string $uname
     * @return mixed
     */
    public function retrieveByUsername($uname)
    {
        global $DBobject;
    
        $sql = "SELECT * FROM tbl_user
				WHERE user_email = :uname AND user_deleted IS NULL";
         
        $res  = $DBobject->wrappedSql($sql, array( ":uname" => $uname ));
    
        return $res[0];
    }
    
    /**
     * Get a single non-deleted record from tbl_user given the phone
     * On error return false
     * Require string: username
     *
     * @param string $phone
     * @return mixed
     */
    public function retrieveByPhone($phone)
    {
        global $DBobject;
    
        $sql = "SELECT * FROM tbl_user
                WHERE user_phone = :phone AND user_deleted IS NULL";
         
        $res  = $DBobject->wrappedSql($sql, array( ":phone" => $phone ));
    
        return $res[0];
    }
    
    /**
     * Get a single non-deleted record from tbl_user given the user id
     * On error return false
     * Require int: user_id
     *
     * @param int $id
     * @return mixed
     */
    public function retrieveById($id)
    {
        global $DBobject;
    
        $sql = "SELECT * FROM tbl_user WHERE user_id = :id AND user_deleted IS NULL";
    
        $res  = $DBobject->wrappedSql($sql, array( ":id" => $id ));
    
        return $res[0];
    }
    
    
    /**
     * Get a user record in tbl_user given the email/password and return associative array: ('id', 'gname', 'surname', 'email')
     * On error return associative array: ('error')
     * Require strings:  email and password
     *
     * @param string $email
     * @param string $pass
     * @return array
     */
    public function authenticate($emailorphone, $pass, $admin = false)
    {
        global $DBobject;
        $encrypt = "new";
        $user_arr = array();
        $isValidPassword = isValidPassword($pass);
        
        $sql = "SELECT * FROM tbl_user WHERE (user_email = :emailorphone or user_phone = :emailorphone) AND user_deleted IS NULL";
        $params = ["emailorphone" => $emailorphone];
        $res = $DBobject->wrappedSql($sql, $params);
        $temp_str = getPass($res[0]['user_username'], $pass);
        if ($admin || ($res && $res[0]['user_password']===$temp_str)) {
            $user_arr["id"]=$res[0]["user_id"];
            $user_arr["oid"]=$res[0]["user_object_id"];
            $user_arr["gname"]=$res[0]["user_gname"];
            $user_arr["surname"]='';
            $user_arr["sex"]=$res[0]["user_sex"];
            $user_arr["email"]=$res[0]["user_email"];
            $user_arr["phone"]=$res[0]["user_phone"];
            $user_arr["user_hearabout"]=$res[0]["user_hearabout"];
            $user_arr["user_want_promo"]=$res[0]["user_want_promo"];
            $user_arr["strong_password"]=$isValidPassword;
        } else {
            $user_arr["error"] = "用户不存在或密码错误";
        }
        return $user_arr;
    }
    
  
    
    
    /**
     *
     * @param unknown $data
     * @return multitype:string
     */
    function UpdateDetails($data)
    {
        global $DBobject;

        //判断用户是否存在
        if ($res = $this->retrieveById($data['user_id'])) {
            //检查邮箱是否被占用
            if (!empty($data['user_email'])) {
                $res2 = $this->retrieveByUsername($data['user_email']);
                if (!empty($res2) && $res2['user_id'] != $res['user_id']) {
                    return array( 'error' => "该邮箱 '{$data['user_email']}' 已被其他用户使用，请更换。");
                }
            }
            //检查手机号是否被占用
            if (!empty($data['user_phone'])) {
                $res2 = $this->retrieveByPhone($data['user_phone']);
                if (!empty($res2) && $res2['user_id'] != $res['user_id']) {
                    return array( 'error' => "该手机号 '{$data['user_phone']}' 已被其他用户使用，请更换。");
                }
            }

            $data['user_email'] = empty($data['user_email'])?$res['user_email'] : $data['user_email'];
            $data['user_phone'] = empty($data['user_phone'])?$res['user_phone'] : $data['user_phone'];
            $data['user_want_promo'] = ($data['user_want_promo'] === 1 || $data['user_want_promo'] === 0)? $data['user_want_promo'] : $res['user_want_promo'];
            $data['user_hearabout'] = (!empty($data['user_hearabout']))? $data['user_hearabout'] : $res['user_hearabout'];
            $data['user_warning'] = (!empty($data['user_warning']))? $data['user_warning'] : $res['user_warning'];
            
            $params = array (
                    ":id" => $res['user_id'],
                    ":gname" => $data['user_gname'],
                    ":sex" => $data['user_sex'],
                    ":username" => $res['user_username'],
                    ":email" => $data['user_email'],
                    ":phone" => $data['user_phone'],
                    ":want_promo" => $data['user_want_promo'],
                    ":user_hearabout" => $data['user_hearabout'],
                    ":user_warning" => $data['user_warning'],
                    ":ip" => $_SERVER['REMOTE_ADDR'],
                    ":browser" => $_SERVER['HTTP_USER_AGENT']
            );
            $sql = "UPDATE tbl_user SET user_username = :username, user_email = :email, user_gname = :gname, user_phone = :phone, user_sex = :sex, user_ip = :ip, user_want_promo = :want_promo, user_hearabout = :user_hearabout, user_browser = :browser, user_warning = :user_warning, user_modified = now()
                            WHERE user_id = :id ";
             
            if ($DBobject->wrappedSql($sql, $params)) {
                saveInLog('Edit', 'tbl_user', $res['user_id']);
                return array ('success' => '您的个人信息已经更新。');
            }
            return array ('error' => '链接错误，请重试！');
        }
        return array( 'error' => "该用户没有找到。");
    }
 
    
    /**
     * Update the password field given the email in tbl_user and return associative array: ('success')
     * On error return associative array: ('error')
     * Require strings:  email and password
     *
     * @param string $email
     * @return array
     */
    public function resetPassword($email)
    {
        global $DBobject,$SMARTY;
    
        if ($res = $this->RetrieveByUsername($email)) {
            $newPass = genRandomString(10);
            $temp_str = getPass($email, $newPass);
            
            $params = array (
                            ":id" => $res['user_id'],
                            ":token" => $temp_str,
                            ":ip" => $_SERVER['REMOTE_ADDR'],
                            ":browser" => $_SERVER['HTTP_USER_AGENT']
            );
            $sql = "UPDATE tbl_user SET user_token = :token, user_token_date = now() , user_ip = :ip, user_browser = :browser, user_modified = now()
                   WHERE user_id = :id ";

            if ($DBobject->wrappedSql($sql, $params)) {
                return array ('success' => '密码重置邮件已经发送到您的邮箱。',
                                        'token' =>$newPass,
                                        'user_gname' =>$res['user_gname']);
            }
            return array ('error' => 'There was a connection problem. Please, try again!');
        }
        return array( 'error' => "对不起，'{$email}' 没有注册。 检查您的邮箱地址或创建一个用户。");
    }
    
    /**
     * Update the password field given the email in tbl_user and return associative array: ('success')
     * On error return associative array: ('error')
     * Require strings:  email and password
     *
     * @param string $email
     * @return array
     */
    /* function ResetPassword($email){
      global $DBobject,$SMARTY;
    
      if ($res = $this->RetrieveByUsername($email)){
        $newPass = genRandomString(10);
        $temp_str = getPass($email,$newPass);
    
        $params = array (
            ":id" => $res['user_id'],
            ":password" => $temp_str,
            ":ip" => $_SERVER['REMOTE_ADDR'],
            ":browser" => $_SERVER['HTTP_USER_AGENT']
        );
        $sql = "UPDATE tbl_user SET user_password = :password, user_ip = :ip, user_browser = :browser, user_modified = now()
                   WHERE user_id = :id ";
    
        if ( $DBobject->wrappedSql($sql, $params) ) {
          return array ('success' => '密码重置邮件已经发送到您的邮箱。',
              'temp_pass' =>$newPass,
              'user_gname' =>$res['user_gname']);
        }
        return array ('error' => 'There was a connection problem. Please, try again!');
      }
      return array( 'error' => "Sorry, '{$email}' does not appear to be registered with this site. Check your email or please create an account.");
    } */
    
    /**
     * Insert new address in tbl_address and returns address_id
     * Require associative array: (address_user_id, address_name, address_telephone, address_mobile, address_line1, address_line2,
                                address_suburb, address_state, address_country, address_postcode)
     * @param array $addressArr
     * @return int
     */
    function InsertNewAddress($addressArr)
    {
        global $DBobject;
        
        $addressArr['address_country'] = empty($addressArr['address_country'])?'Australia':$addressArr['address_country'];
        $addressArr['address_surname'] = empty($addressArr['address_surname'])?'':$addressArr['address_surname'];
        $params = array (
                ":address_user_id" => $addressArr['address_user_id'],
                ":address_name" => $addressArr['address_name'],
                ":address_surname" => $addressArr['address_surname'],
                ":address_telephone" => $addressArr['address_telephone'],
//     			":address_mobile" => $addressArr['address_mobile'],
                ":address_line1" => $addressArr['address_line1'],
                ":address_suburb" => $addressArr['address_suburb'],
                ":address_state" => $addressArr['address_state'],
                ":address_country" => $addressArr['address_country'],
                ":address_postcode" => $addressArr['address_postcode']
        );
        
        $sql = "SELECT address_id FROM tbl_address WHERE 
    					address_user_id = :address_user_id AND 
    					address_name = :address_name AND  
    					address_surname = :address_surname AND  
    					address_telephone = :address_telephone AND  
    					address_line1 = :address_line1 AND  
    					address_suburb = :address_suburb AND  
    					address_state = :address_state AND  
    					address_country = :address_country AND  
    					address_postcode = :address_postcode AND
    					address_deleted IS NULL";
        
        if ($res = $DBobject->wrappedSql($sql, $params)) {
            $sql = "UPDATE tbl_address SET address_modified = now()  WHERE address_id = :id ";
            $DBobject->wrappedSql($sql, array(':id'=>$res[0]['address_id']));
            return $res[0]['address_id'];
        } else {
            $sql = "INSERT INTO tbl_address (
	        						address_user_id, address_name, address_surname, address_telephone, address_line1, 
									address_suburb, address_state, address_country, address_postcode,	address_created
									)
								VALUES (
									:address_user_id, :address_name, :address_surname, :address_telephone, :address_line1, 
									:address_suburb, :address_state, :address_country, :address_postcode,	now()
								)";
        
            if ($DBobject->wrappedSql($sql, $params)) {
                return $DBobject->wrappedSqlIdentity();
            }
        }
        return 0;
    }
    
    /**
     * Return array recordset given the address_id
     *
     * @param int $addressId
     * @return array
     */
    function GetAddress($addressId)
    {
        global $DBobject;
    
        $sql = "SELECT * FROM tbl_address WHERE address_deleted IS NULL AND address_id = :id ";
        $res = $DBobject->wrappedSql($sql, array(':id' => $addressId));
        return $res[0];
    }
    
    /**
     * Return array recordset given the field address_user_id
     *
     * @param int $addressId
     * @return array
     */
    function GetUsersAddresses($addressUserId, $orderby = '', $limit = 10)
    {
        global $DBobject;

        if (!empty($orderby)) {
            $orderby = 'ORDER BY ' . $orderby;
        } else {
            $orderby = 'ORDER BY address_modified DESC';
        }
        $sql = "SELECT * FROM tbl_address WHERE address_deleted IS NULL AND address_user_id = :id " . $orderby . " LIMIT " . $limit;
        return $DBobject->wrappedSql($sql, array(':id' => $addressUserId));
    }
    
    
    
    
    function DeleteUSer($userId)
    {
        global $DBobject;
    
        if ($res = $this->RetrieveById($userId)) {
            $params = array (
                    ":id" => $userId,
                    ":ip" => $_SERVER['REMOTE_ADDR'],
                    ":browser" => $_SERVER['HTTP_USER_AGENT']
            );
            $sql = "UPDATE tbl_user SET user_ip = :ip, user_browser = :browser, user_deleted = now(), user_modified = now() WHERE user_id = :id ";
            if ($DBobject->wrappedSql($sql, $params)) {
                return array ('success' => 'The member has been successfully deleted.');
            }
            return array ('error' => 'There was a connection problem. Please, try again!');
        }
        return array( 'error' => "Unable to find the existing member.");
    }

    public function deleteUserByObjectId($uoid)
    {
        global $DBobject;
    
        $params = array (
                ":id" => $uoid,
                ":uoid" => null,
                ":ip" => $_SERVER['REMOTE_ADDR'],
                ":browser" => $_SERVER['HTTP_USER_AGENT']
        );
        $sql = "UPDATE tbl_user SET user_object_id = :uoid, user_ip = :ip, user_browser = :browser, user_deleted = now(), user_modified = now() WHERE user_object_id = :id ";
        if ($DBobject->wrappedSql($sql, $params)) {
            return true;
        }
        return false;
    }
    
     
     /**
     * Authenticate the user using Facebook account.
     * First time, Insert a new record in tbl_user with additional Facebook info and return associative array: ('id', 'gname', 'surname', 'email', 'social_name', 'social_id')
     * On existing, just return associative array: ('id', 'gname', 'surname', 'email', 'social_name', 'social_id')
     * On error return associative array: ('error')
     * Require associative array: ('id', 'first_name', 'last_name', 'email', additional fields )
     *
     * @param array $user
     * @return array
     */
    function AuthenticateFacebook($user)
    {
        global $DBobject;
        
        if ($user['id']) {
            if ($res = $this->RetrieveByUsername($user['id'])) { // ALREADY REGISTERED
                $user_arr["id"]=$res["user_id"];
                $user_arr["gname"]=$res["user_gname"];
                $user_arr["surname"]=$res["user_surname"];
                $user_arr["email"]=$res["user_email"];
                $user_arr["social_name"]=$res["user_social_name"];
                $user_arr["social_id"]=$res["user_social_id"];
                //SaveAdminLogIn($row['admin_id']);		//<<<<<<<<<======= Login log????
            } else {            //REGISTER WITH FACEBOOK DETAILS
                $params = array (
                        ":gname" => $user['first_name'],
                        ":surname" => $user['last_name'],
                        ":email" => $user['email'],
                        ":social_name" => 'facebook',
                        ":social_id" => $user['id'],
                        ":social_info" => json_encode($user),
                        ":ip" => $_SERVER['REMOTE_ADDR'],
                        ":browser" => $_SERVER['HTTP_USER_AGENT']
                );
                
                $sql = "INSERT INTO tbl_user ( user_username, user_gname, user_surname, user_email, user_social_name, user_social_id, user_social_info, user_ip, user_browser, user_created )
									values( :social_id, :gname, :surname, :email, :social_name, :social_id, :social_info, :ip, :browser, now() )";
                if ($DBobject->wrappedSql($sql, $params)) {
                    $userId =  $DBobject->wrappedSqlIdentity();
                    $user_arr = array (
                            "id" => $userId,
                            "gname" => $user['first_name'],
                            "surname" => $user['last_name'],
                            "email" => $user['email'],
                            "social_name" => 'facebook',
                            "social_id" => $user['id']
                    );
                }
                
                // STORE DATA IN FACEBOOK TABLE
                if (!empty($user['birthday'])) {
                    $bd = explode('/', $user['birthday']);
                    $bday = $bd[2] . '-' . $bd[0] . '-' . $bd[1];
                }
                $params = array (
                        ":facebook_id" => $user['id'],
                        ":facebook_name" => $user['name'],
                        ":facebook_first_name" => $user['first_name'],
                        ":facebook_last_name" => $user['last_name'],
                        ":facebook_email" => $user['email'],
                        ":facebook_username" => $user['username'],
                        ":facebook_birthday" => $bday,
                        ":facebook_gender" => $user['gender'],
                        ":facebook_location_id" => $user['location']['id'],
                        ":facebook_location_name" => $user['location']['name'],
                );
                $sql = "INSERT INTO tbl_facebook ( facebook_id, facebook_name, facebook_first_name, facebook_last_name, facebook_email, facebook_username, facebook_birthday, facebook_gender, facebook_location_id, facebook_location_name, facebook_created )
									values( :facebook_id, :facebook_name, :facebook_first_name, :facebook_last_name, :facebook_email, :facebook_username, :facebook_birthday, :facebook_gender, :facebook_location_id, :facebook_location_name, now() )";
                $DBobject->wrappedSql($sql, $params);
            }
            return $user_arr;
        }
    
        return array( "error" => 'Missing Facebook ID.');
    }
    
    
    function AuthenticateTwitter()
    {
        global $DBobject;
    }
}
